classdef ChangeOfVariables < handle
    properties
        
    end
    
    methods (Static)
        
        function theta = change_variable_minone_one(phi, theta_lb, theta_ub)
        % Reverse change of variables where phi on interval [-1,1].
        %
        % Args:
        %     phi (double): transformed variable
        %     theta_lb (double): lower-bound of :math:`\theta`
        %     theta_ub (double): upper-bound of :math:`\theta`
        %
            
            theta = 1/2.*((1-phi).*theta_lb + (1+phi).*theta_ub);
        end
        
        function dtheta_dphi = change_variable_minone_one_deriv(phi, theta_lb, theta_ub)
        % derivative dtheta/dphi corresponding to change of
        % variables formula
        % :code:`change_variable_minone_one`
        %
        % Args:
        %     phi (double): transformed variable
        %     theta_lb (double): lower-bound of :math:`\theta`
        %     theta_ub (double): upper-bound of :math:`\theta`
        %
            
            dtheta_dphi = 1/2 .*(theta_ub - theta_lb);
        end        
        
        function theta = change_variable_minone_one_log(phi, theta_lb, theta_ub)
            % Reverse change of variables where phi = log(theta)
            % on interval [-1,1]. :code:`theta_lb` needs to be >0 otherwise
            % get complex values.
            %
            % Args:
            %     phi (double): transformed variable
            %     theta_lb (double): lower-bound of :math:`\theta`
            %     theta_ub (double): upper-bound of :math:`\theta`
            %
            log_theta_lb = log(theta_lb);    
            log_theta_ub = log(theta_ub);    
                
            theta = exp(1).^((1/2).*(log_theta_lb+(-1).*phi.* ...
                log_theta_lb+log_theta_ub+ ...
                phi.*log_theta_ub));
        end
        
        function dtheta_dphi = change_variable_minone_one_log_deriv(phi, theta_lb,theta_ub)
            % derivative dtheta/dphi corresponding to change of
            % variables formula
            % :code:`change_variable_minone_one_log`. :code:`theta_lb` needs to be >0 otherwise
            % get complex values.
            %
            % Args:
            %     phi (double): transformed variable
            %     theta_lb (double): lower-bound of :math:`\theta`
            %     theta_ub (double): upper-bound of :math:`\theta`
            
            log_theta_lb = log(theta_lb);    
            log_theta_ub = log(theta_ub);    
                
            dtheta_dphi = (1/2).*exp(1).^((1/2).*(log_theta_lb-phi.* ...
                log_theta_lb+ ...
                log_theta_ub+phi.*log_theta_ub)).*((-1).*log_theta_lb+log_theta_ub);
        end
        
        function [theta, dtheta_dphi] = change_variable_zero_one(phi, theta_lb, theta_ub)
            % phi is on [0,1], theta is on [theta_lb, theta_ub]
            % for integration: integral(theta,theta_lb,theta_ub) =
            % integral(theta(phi).*dtheta_dphi,0,1)
            %
            % Args:
            %     phi (double): transformed variable
            %     theta_lb (double): lower-bound of :math:`\theta`
            %     theta_ub (double): upper-bound of :math:`\theta`
            
            theta = theta_lb - theta_lb.*phi + theta_ub.*phi;
            dtheta_dphi = theta_ub - theta_lb;
        end    
    end
end